package com.syqc.netlib.errorhandler

import android.net.ParseException
import com.google.gson.JsonParseException
import com.syqc.comlib.R
import com.syqc.netlib.ExpeContext
import org.json.JSONException
import retrofit2.HttpException
import java.net.ConnectException
import java.net.SocketTimeoutException
import javax.net.ssl.SSLHandshakeException

object ExceptionHandle {
    private const val UNAUTHORIZED = 401
    private const val FORBIDDEN = 403
    private const val NOT_FOUND = 404
    private const val NO_AGENT = 407
    private const val REQUEST_TIMEOUT = 408
    private const val INTERNAL_SERVER_ERROR = 500
    private const val BAD_GATEWAY = 502
    private const val SERVICE_UNAVAILABLE = 503
    private const val GATEWAY_TIMEOUT = 504

    fun handlerException(e: Throwable): ResponseThrowable {
        val ex: ResponseThrowable
        when (e) {
            is HttpException -> {
                ex = ResponseThrowable(e, ERROR.HTTP_ERROR, "")
                when (e.code()) {
                    UNAUTHORIZED -> ex.message = ExpeContext.getDescById(R.string.net_error_401)
                    FORBIDDEN -> ex.message = ExpeContext.getDescById(R.string.net_error_403)
                    NOT_FOUND -> ex.message = ExpeContext.getDescById(R.string.net_error_404)
                    NO_AGENT -> ex.message = ExpeContext.getDescById(R.string.net_error_407)
                    REQUEST_TIMEOUT -> ex.message = ExpeContext.getDescById(R.string.net_error_408)
                    INTERNAL_SERVER_ERROR -> ex.message =
                       ExpeContext.getDescById(R.string.net_error_500)
                    BAD_GATEWAY -> ex.message = ExpeContext.getDescById(R.string.net_error_502)
                    SERVICE_UNAVAILABLE -> ex.message =
                       ExpeContext.getDescById(R.string.net_error_503)
                    GATEWAY_TIMEOUT -> ex.message = ExpeContext.getDescById(R.string.net_error_504)
                    else -> ex.message = ExpeContext.getDescById(R.string.net_error_unknown)
                }
            }
            is ServerException -> {
                ex = ResponseThrowable(
                    e,
                    e.code,
                    e.message
                )

            }
            is JsonParseException, is JSONException, is ParseException -> {
                ex = ResponseThrowable(
                    e,
                    ERROR.PARSE_ERROR,
                   ExpeContext.getDescById(R.string.net_error_1001)
                )
            }
            is ConnectException -> {
                ex = ResponseThrowable(
                    e,
                    ERROR.NETWORD_ERROR,
                   ExpeContext.getDescById(R.string.net_error_1002)
                )

            }
            is SSLHandshakeException -> {
                ex = ResponseThrowable(
                    e,
                    ERROR.SSL_ERROR,
                   ExpeContext.getDescById(R.string.net_error_1005)
                )

            }
            is SocketTimeoutException -> {
                ex = ResponseThrowable(
                    e,
                    ERROR.TIMEOUT_ERROR,
                   ExpeContext.getDescById(R.string.net_error_1006)
                )
            }
            else -> {
                ex = ResponseThrowable(
                    e,
                    ERROR.UNKNOWN,
                   ExpeContext.getDescById(R.string.net_error_unknown)
                )
            }
        }
        return ex
    }

    /** 约定异常 */
    object ERROR {
        /** 未知错误 */
        const val UNKNOWN = 1000

        /** 解析错误 */
        const val PARSE_ERROR = 1001

        /** 网络错误 */
        const val NETWORD_ERROR = 1002

        /** 协议出错 */
        const val HTTP_ERROR = 1003

        /** 证书出错 */
        const val SSL_ERROR = 1005

        /** 连接超时 */
        const val TIMEOUT_ERROR = 1006
    }

    class ResponseThrowable(
        throwable: Throwable,
        var code: Int,
        override var message: String
    ) : Exception(throwable)

    class ServerException(
        var code: Int = 0,
        override var message: String
    ) : RuntimeException()

}